package javaproject;

import javax.media.j3d.LineArray;
import javax.media.j3d.QuadArray;
import javax.media.j3d.Shape3D;
import javax.vecmath.Color3f;
import javax.vecmath.Vector3d;
import javax.media.j3d.TransformGroup;
import javax.media.j3d.Appearance;

abstract class BasicPlane extends MyPrimitive{
    static final int NORMAL_X = 0;
    static final int NORMAL_Y = 1;
    static final int NORMAL_Z = 2;

    private double x,y,z;
    public double x1,y1,z1;
    public double x2,y2,z2;
    public int normal;
    public float alpha;
    protected float offset;   //方塊面內縮值，減少反鋸齒錯誤

    BasicPlane(float[] dim, double[] pos, int normal, Appearance app, float alpha, float offset)
    {
        super(0,0,0,app);
	this.normal = normal;
        switch(normal)
        {
            case NORMAL_X:
                this.x1 = pos[0];
                this.y1 = pos[1]+dim[1];
                this.z1 = pos[2]+dim[2];
                this.x2 = pos[0];
                this.y2 = pos[1]-dim[1];
                this.z2 = pos[2]-dim[2];
                break;
            case NORMAL_Y:
                this.x1 = pos[0]+dim[0];
                this.y1 = pos[1];
                this.z1 = pos[2]+dim[2];
                this.x2 = pos[0]-dim[0];
                this.y2 = pos[1];
                this.z2 = pos[2]-dim[2];
                break;
            case NORMAL_Z:
                this.x1 = pos[0]+dim[0];
                this.y1 = pos[1]+dim[1];
                this.z1 = pos[2];
                this.x2 = pos[0]-dim[0];
                this.y2 = pos[1]-dim[1];
                this.z2 = pos[2];
                break;
        }
        this.alpha = alpha;
        this.offset = offset;
        transG.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
    }
    public void move(double x, double y, double z)
    {
        this.x1 += x-(x1+x2)/2;
        this.y1 += y-(y1+y2)/2;
        this.z1 += z-(z1+z2)/2;
        this.x2 += x-(x1+x2)/2;
        this.y2 += y-(y1+y2)/2;
        this.z2 += z-(z1+z2)/2;
        translate.set(new Vector3d(x,y,z));
        transG.setTransform(translate);
    }
}
class Plane extends BasicPlane{
    Plane(float[] dim, double[] pos, int normal, Appearance app, float alpha, float offset)
    {
        super(dim,pos,normal,app,alpha,offset);

        double offsetX = offset * (x1-x2);
        double offsetY = offset * (y1-y2);
        double offsetZ = offset * (z1-z2);
        double[] planeVertices = new double[24];
        switch(normal)
        {
            case NORMAL_X:
                planeVertices = new double[]
                {
                    x1,y1+offsetY,z1+offsetZ,   x2,y2-offsetY,z1+offsetZ,
                    x2,y2-offsetY,z2-offsetZ,   x1,y1+offsetY,z2-offsetZ,
		    x1,y1+offsetY,z2-offsetZ,	x2,y2-offsetY,z2-offsetZ,
                    x2,y2-offsetY,z1+offsetZ,	x1,y1+offsetY,z1+offsetZ
                };
                break;
            case NORMAL_Y:
                planeVertices = new double[]
                {
                    x1-offsetX,y1,z1-offsetZ,   x1-offsetX,y2,z2+offsetZ,
                    x2+offsetX,y2,z2+offsetZ,   x2+offsetX,y1,z1-offsetZ,
                    x2+offsetX,y1,z1-offsetZ,	x2+offsetX,y2,z2+offsetZ,
		    x1-offsetX,y1,z1-offsetZ,	x1-offsetX,y2,z2+offsetZ
                };
                break;
            case NORMAL_Z:
                planeVertices = new double[]
                {
                    x1-offsetX,y1-offsetY,z1,   x2+offsetX,y1-offsetY,z2,
                    x2+offsetX,y2+offsetY,z2,   x1-offsetX,y2+offsetY,z1,
                    x1-offsetX,y2+offsetY,z1,	x2+offsetX,y2+offsetY,z2,
		    x2+offsetX,y1-offsetY,z2,	x1-offsetX,y1-offsetY,z1
                };
                break;
        }
        QuadArray plane = new QuadArray(8, QuadArray.COORDINATES | QuadArray.COLOR_4);
        Color3f intrinsicColor = new Color3f();
        app.getColoringAttributes().getColor(intrinsicColor);
        float[] planeColor = new float[32];
        for(int i = 0; i < 8; i++)
        {
            planeColor[i*4] = intrinsicColor.get().getRed();
            planeColor[i*4+1] = intrinsicColor.get().getGreen();
            planeColor[i*4+2] = intrinsicColor.get().getBlue();
            planeColor[i*4+3] = alpha;
        }
        plane.setCoordinates(0, planeVertices);
        plane.setColors(0, planeColor);
        shape = new Shape3D(plane, app);
        transG.addChild(shape);
    }
}
class PlaneFrame extends BasicPlane{
    PlaneFrame(float[] dim, double[] pos, int normal, Appearance app, float alpha)
    {
        super(dim,pos,normal,app,alpha,0);

                    double[] lineVertices = new double[12];
        switch(normal)
        {
            case NORMAL_X:
                lineVertices = new double[]
                {
                    x1,y1,z1,   x2,y2,z1,
                    x2,y2,z1,   x2,y2,z2,
                    x2,y2,z2,   x1,y1,z2,
                    x1,y1,z2,   x1,y1,z1
                };
                break;
            case NORMAL_Y:
                lineVertices = new double[]
                {
                    x1,y1,z1,   x1,y2,z2,
                    x1,y2,z2,   x2,y2,z2,
                    x2,y2,z2,   x2,y1,z1,
                    x2,y1,z1,   x1,y1,z1
                };
                break;
            case NORMAL_Z:
                lineVertices = new double[]
                {
                    x1,y1,z1,   x2,y1,z2,
                    x2,y1,z2,   x2,y2,z2,
                    x2,y2,z2,   x1,y2,z1,
                    x1,y2,z1,   x1,y1,z1
                };
                break;
        }
        LineArray line = new LineArray(8, LineArray.COORDINATES | LineArray.COLOR_4);
        Color3f intrinsicColor = new Color3f();
        app.getColoringAttributes().getColor(intrinsicColor);
        float[] lineColor = new float[32];
        for(int i = 0; i < 8; i++)
        {
            lineColor[i*4] = intrinsicColor.get().getRed();
            lineColor[i*4+1] = intrinsicColor.get().getGreen();
            lineColor[i*4+2] = intrinsicColor.get().getBlue();
            lineColor[i*4+3] = alpha;
        }
        line.setCoordinates(0, lineVertices);
        line.setColors(0, lineColor);
        shape = new Shape3D(line, app);
        transG.addChild(shape);
    }
}